import * as THREE from 'three';
import { WEBGL } from '../../../../../node_modules/three/examples/jsm/WebGL.js';

const Tz3DrawType = {
  DEFAULT: 0, // 无
  LINE: 1, // 线
  CIRCLE: 2, // 圆
  SQUARE: 3, // 正方形
  BOX_GEOMETRY: 4, // 旋转的立方体
  OBJECT: 5, // 对象
};
class Tz3dViewport {
  constructor({ viewportDom }) {
    this.viewportDom = viewportDom;
    this.scene = null; // 场景
    this.camera = null; // 相机：视野角度FOV，长宽比、远剪切面，近剪切面
    this.renderer = null; // 渲染器
    this.canvasSize = viewportDom
      ? [viewportDom.clientWidth, viewportDom.clientHeight]
      : [0, 0]; // 所在DOM的宽、高
    this.cube = null;
    this._initView();
  }

  _initView() {
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(
      45,
      this.canvasSize[0] / this.canvasSize[1],
      1,
      500
    );

    this.renderer = new THREE.WebGLRenderer();
    this.renderer.setSize(this.canvasSize[0], this.canvasSize[1]);
    this.viewportDom.appendChild(this.renderer.domElement); // 将渲染器加入到展示的DOM中

    let _self = this;
    if (WEBGL.isWebGLAvailable()) {
      // Initiate function or other initializations here
      animate();
    } else {
      // 若是浏览器不支持，则错误提示
      let warning = WEBGL.getWebGLErrorMessage();
      this.viewportDom.appendChild(warning);
    }

    function animate() {
      requestAnimationFrame(animate); // 使得渲染器能够在每次屏幕刷新时对场景进行绘制，当用户切换到其它的标签页时，它会暂停，因此不会浪费用户宝贵的处理器资源，以及损耗电池的使用寿命
      if (_self.cube) _self.cube.rotation.x += 0.01;
      if (_self.cube) _self.cube.rotation.y += 0.01;
      _self.renderer.render(_self.scene, _self.camera);
    }
  }

  createObjects(type) {
    switch (type) {
      case Tz3DrawType.LINE:
        this.createLine();
        break;
      case Tz3DrawType.CIRCLE:
        break;
      case Tz3DrawType.SQUARE:
        this.createSquare();
        break;
      case Tz3DrawType.BOX_GEOMETRY:
        this.createBox();
        break;
      case Tz3DrawType.OBJECT:
        this.createObject();
        break;
      default:
        break;
    }
  }

  createBox() {
    // 创建一个立方体
    let geometry = new THREE.BoxGeometry(1, 1, 1); // 立方体
    let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 材质，以便赋予立方体颜色（此处绿色：0x00ff00）
    this.cube = new THREE.Mesh(geometry, material); // 网格
    this.scene.add(this.cube);
    this.camera.position.z = 5;
  }

  createLine() {
    this.camera = new THREE.PerspectiveCamera(
      75,
      this.canvasSize[0] / this.canvasSize[1],
      0.1,
      1000
    );
    this.camera.position.set(0, 0, 100);
    this.camera.lookAt(0, 0, 0);
    // 创建 材质
    let material = new THREE.LineBasicMaterial({ color: 0x0000ff });
    // 创建 顶点
    let geometry = new THREE.Geometry();
    geometry.vertices.push(new THREE.Vector3(-10, 0, 0));
    geometry.vertices.push(new THREE.Vector3(10, 0, 0));
    // 创建 线
    let line = new THREE.Line(geometry, material);
    this.scene.add(line);
    this.renderer.render(this.scene, this.camera);
  }

  createSquare() {
    this.camera = new THREE.PerspectiveCamera(
      75,
      this.canvasSize[0] / this.canvasSize[1],
      1,
      500
    );
    this.camera.position.set(0, 0, 100);
    this.camera.lookAt(0, 0, 0);
    // 创建 材质
    let material = new THREE.LineDashedMaterial({ color: 0x0000ff });
    // 创建 顶点
    let geometry = new THREE.Geometry();
    geometry.vertices.push(new THREE.Vector3(-20, 0, 0));
    geometry.vertices.push(new THREE.Vector3(0, 20, 0));
    geometry.vertices.push(new THREE.Vector3(20, 0, 0));
    geometry.vertices.push(new THREE.Vector3(0, -20, 0));
    geometry.vertices.push(new THREE.Vector3(-20, 0, 0));
    // 创建 线
    let line = new THREE.Line(geometry, material);
    this.scene.add(line);

    let geometryTwo = new THREE.Geometry();
    geometryTwo.vertices.push(new THREE.Vector3(0, 15, 0));
    geometryTwo.vertices.push(new THREE.Vector3(0, -15, 0));
    let lineTwo = new THREE.Line(geometryTwo, material);
    this.scene.add(lineTwo);

    this.renderer.render(this.scene, this.camera);
  }

  createObject() {
    let MAX_POINTS = 500;

    // geometry
    let geometry = new THREE.BufferGeometry();

    // attributes
    let positions = new Float32Array(MAX_POINTS * 3); // 3 vertices per point
    geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));

    // draw range
    let drawCount = 2; // draw the first 2 points, only
    geometry.setDrawRange(0, drawCount);

    // material
    let material = new THREE.LineBasicMaterial({
      color: 0xff0000,
      linewidth: 2,
    });

    // line
    let line = new THREE.Line(geometry, material);
    this.scene.add(line);

    let positionsArr = line.geometry.attributes.position.array;
    let x, y, z, index;
    x = y = z = index = 0;
    for (let i = 0, l = MAX_POINTS; i < l; i++) {
      positionsArr[index++] = x;
      positionsArr[index++] = y;
      positionsArr[index++] = z;

      x += (Math.random() - 0.5) * 30;
      y += (Math.random() - 0.5) * 30;
      z += (Math.random() - 0.5) * 30;
    }

    this.renderer.render(this.scene, this.camera);
  }
}

export { Tz3DrawType };
export { Tz3dViewport };
